package com.hliushi.learn.controller;

import com.hliushi.learn.bean.Reader;
import com.hliushi.learn.response.JsonResult;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletContext;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName ListenerController
 * @Description TODO
 * @Author liushi
 * @Date 2021/7/8 14:54
 * @Version V1.0
 **/
@RestController
@RequestMapping("/listener")
public class ListenerController {


    /**
     * @param
     * @return
     */
    @ApiOperation("")
    @GetMapping("/reader")
    public Reader getReader(HttpServletRequest request) {
        ServletContext servletContext = request.getServletContext();
        return (Reader) servletContext.getAttribute("reader");
    }


    /**
     * 监听Servlet上下文, 从缓存中获取所有读者信息 -- 4ms
     * http://localhost:8001/listener/reader/all
     * #
     * 获取所有读者信息    -- 90ms
     * http://localhost:8001/reader/getall
     *
     * @param request HttpServletRequest
     * @return
     */
    @ApiOperation("监听Servlet上下文, 从缓存中获取所有读者信息")
    @GetMapping("/reader/all")
    public JsonResult<List<Reader>> getReaderAll(HttpServletRequest request) {
        ServletContext servletContext = request.getServletContext();
        ArrayList<Reader> readerList = null;
        Object obj = servletContext.getAttribute("readerList");
        if (obj != null) {
            readerList = (ArrayList<Reader>) obj;
        }

        return new JsonResult<>(readerList);
    }


    /**
     * 获取当前在线人数, 该方法有bug
     * #
     * 在一个浏览器中输入 localhost:8080/listener/total, 可以看到返回的结果是1
     * 再打开一个浏览器, 请求相同地址可以看到count是2
     * 但是如果关闭一个浏览器再打开, 理论上应该还是2, 但是实际测试却是3
     * 原因是session销毁的方法没有执行. 当重新打开时, 服务器找不到用户原来的session, 于是有重新创建一个session
     *
     * @param request HttpServletRequest
     * @return jsonResult
     */
    @ApiOperation("使用HttpSessionListener统计在线用户数的监听器 -- 有bug")
    @GetMapping("/total")
    public JsonResult<String> getTotalUser(HttpServletRequest request) {
        Integer count = (Integer) request.getSession().getServletContext().getAttribute("count");
        return new JsonResult<>("当前在线人数: " + count);
    }


    /**
     * 把上面的方法改造一下
     *
     * @param request
     * @return
     */
    @ApiOperation("使用HttpSessionListener统计在线用户数的监听器")
    @GetMapping("/total2")
    public JsonResult<String> getTotalUser2(HttpServletRequest request, HttpServletResponse response) {
        /**
         * 该处理逻辑是让服务器记得原来那个session, 即把原来的sessionId记录在浏览器中,
         * 下一次再打开时, 把这个sessionId传过去, 这样服务器就不会重新再创建了
         */
        Cookie cookie;
        try {
            cookie = new Cookie("JSESSIONID", URLEncoder.encode(request.getSession().getId(), "utf-8"));
            cookie.setPath("/");
            // 设置cookie有效期为两天, 设置长一点
            cookie.setMaxAge(60 * 60 * 24 * 2);
            response.addCookie(cookie);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        Integer count = (Integer) request.getSession().getServletContext().getAttribute("count");
        return new JsonResult<>("当前在线人数: " + count);
    }

    /**
     * 使用ServletRequestListener获取用户的访问信息
     *
     * @param request
     * @return
     */
    @ApiOperation("使用ServletRequestListener获取用户的访问信息")
    @GetMapping("/request")
    public JsonResult<Void> getRequestInfo(HttpServletRequest request) {
        // 16:06:47.379 [http-nio-8001-exec-6] INFO  c.h.l.l.MyServletRequestListener - session id为: null
        // 16:06:47.379 [http-nio-8001-exec-6] INFO  c.h.l.l.MyServletRequestListener - request url: ../listener/request
        // requestListener中的初始化的name数据: hliushi
        // 16:06:47.381 [http-nio-8001-exec-6] INFO  c.h.l.l.MyServletRequestListener - request end
        // 16:06:47.381 [http-nio-8001-exec-6] INFO  c.h.l.l.MyServletRequestListener - request域中保存的name值为: hliushi

        System.out.println("requestListener中的初始化的name数据: " + request.getAttribute("name"));
        return new JsonResult<>();
    }
}
